home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Mac Source / Graphics.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-24  |  7.5 KB  |  394 lines  |  [TEXT/CWIE]

  1. /*
  2. ** File:        Graphics.c
  3. **
  4. ** Written by:    Bill Hayden
  5. **                Nikol Software
  6. **
  7. ** Copyright © 1995 Nikol Software
  8. ** All rights reserved.
  9. */
  10.  
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <QDOffscreen.h>
  16. #include <Palettes.h>
  17.  
  18. #include "Failure.h"
  19. #include "wt.h"
  20. #include "error.h"
  21. #include "framebuf.h"
  22. #include "input.h"
  23. #include "view.h"
  24. #include "world.h"
  25. #include "object.h"
  26. #include "graphics.h"
  27. #include "render.h"
  28. #include "MacWT.h"
  29. #include "Constants.h"
  30. #include "StringUtils.h"
  31. #include "ShowHideMenubar.h"
  32.  
  33. #include <math.h>
  34.  
  35. #if GENERATING68K
  36. #include "Blit.h"
  37. #endif
  38.  
  39. /**/
  40.  
  41.  
  42. static    GWorldPtr    gWorld;
  43. static    Rect        gWorldRect;
  44.         Rect        gDestinationRect;
  45.         Rect        gInformationRect;
  46.         DialogRef    gWindow;
  47.         DialogRef    gBackgroundWindow;
  48.         long        gStartTicks, gFrameCount;
  49. static    PixMapHandle    srcPixHandle;
  50. static    PixMapHandle    portPixMap;
  51.  
  52.  
  53. /**/
  54.  
  55.  
  56.  
  57.  
  58. Graphics_info *InitGraphics(short width, short height)
  59. {
  60.     static Graphics_info ginfo;
  61.     GDHandle    oldGD;
  62.     GWorldPtr    oldWorld;
  63.     OSErr        err;
  64.  
  65.  
  66.     // Screen width must be multiple of 4...
  67.  
  68.     if (width & 3)
  69.         fatal_error("Screen width must be a multiple of 4.");
  70.     
  71.     GetGWorld(&oldWorld, &oldGD);            // Get main window port
  72.         
  73.     SetRect(&gWorldRect, 0, 0, width, height);
  74.     err = NewGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
  75.     if (err)
  76.         Fail(err, __FILE__, __LINE__, TRUE);
  77.             
  78.     // JCD 10/95 You MUST multiply width times gSizeOfPixel which is > 1 for > 8 bpp
  79.     (*GetGWorldPixMap(gWorld))->rowBytes = 0x8000 | (width * gSizeOfPixel);
  80.  
  81.     SetGWorld(gWorld, nil);
  82.     EraseRect(&gWorld->portRect);
  83.     
  84.     SetGWorld(oldWorld, oldGD);              // Set port to main window
  85.  
  86.     srcPixHandle = GetGWorldPixMap(gWorld);
  87.     HLock((Handle) srcPixHandle);
  88.  
  89.     portPixMap = ((CGrafPtr)qd.thePort)->portPixMap;
  90.      HLock((Handle) portPixMap);
  91.      
  92.     // 8/3/95 JCD ** VERY IMPORTANT **  LockPixels incantation                                                
  93.     // In order to be able to save a ptr to pixels in framebuffer struct 
  94.     // Otherwise, pixels get moved or purged by subsequent calls to malloc and
  95.     // are not at that address anymore!
  96.     
  97.     if (!LockPixels(GetGWorldPixMap(gWorld)))            // make sure everything is kosher
  98.         {
  99.         UpdateGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
  100.         if (!LockPixels(GetGWorldPixMap(gWorld)))
  101.             Fail(ResError(), __FILE__, __LINE__, TRUE);
  102.         }
  103.  
  104. #if GENERATING68K
  105.     InitBlit(*srcPixHandle, *portPixMap, &gWorldRect, &gDestinationRect);
  106. #endif
  107.  
  108.     ginfo.width = width;
  109.     ginfo.height = height;
  110.  
  111.     if (!gTrueColor)
  112.         {
  113.         const short ncolors = 256;
  114.         short x;
  115.  
  116.         ginfo.color_lookup = (long *)NewPtr(sizeof(long) * ncolors);
  117.         for (x = 0; x < ncolors ; x++)
  118.             ginfo.color_lookup[x] = (long)x;
  119.         }
  120.     else
  121.         ginfo.color_lookup = nil;
  122.  
  123.     return &ginfo;
  124. }
  125.  
  126.  
  127. /**/
  128.  
  129.  
  130. void EndGraphics(void)
  131. {
  132.     GDHandle    theGDevice;
  133.  
  134.     if (gWorld) DisposeGWorld(gWorld);
  135.  
  136.     theGDevice = GetMainDevice();
  137.     if ( gScreenDepth != gCurrentDepth )
  138.         SetDepth( theGDevice, gScreenDepth, 0, 0 );
  139. }
  140.  
  141.  
  142. /**/
  143.  
  144.  
  145. void MacAttractMode(void)
  146. {
  147.     if (!gWindow)
  148.         Fail(ResError(), __FILE__, __LINE__, TRUE);
  149.  
  150.     // This is a bit of a hack, I’m afraid…
  151.  
  152.     if (!gGameOn)
  153.         {
  154.         Str255    SplashString = "\pMacWT ";
  155.  
  156.         SetPortWindowPort(gWindow);
  157.  
  158.         pcat(SplashString, gWTVersion);
  159.         pcat(SplashString, "\p, executing "
  160. #if    GENERATINGPOWERPC
  161.         "PowerPC code.");
  162. #else
  163.         "MC680x0 code.");
  164. #endif
  165.  
  166.         BackColor(blackColor);
  167.         ForeColor(whiteColor);
  168.         TETextBox(SplashString + 1, SplashString[0], &gInformationRect, teCenter);
  169.         }
  170. }
  171.  
  172.  
  173. /**/
  174.  
  175.  
  176. void BeginGame(void)
  177. {
  178.     BackColor(blackColor);
  179.     EraseRect(&gInformationRect);
  180.     
  181.     HideCursor();
  182.     SetMBarState(HIDE);
  183.     ShowWindow((WindowRef)gBackgroundWindow);
  184.  
  185.     gGameOn = true;
  186.     if (gPaused)
  187.         TogglePause();
  188.         
  189.     if (!gStartTicks)
  190.         gStartTicks = TickCount();
  191. }
  192.  
  193.  
  194. /**/
  195.  
  196.  
  197.  
  198. int GetRowBytes(void)
  199. {
  200.     return((*GetGWorldPixMap(gWorld))->rowBytes & 0x3FFF);
  201. }
  202.  
  203.  
  204.  
  205. /**/
  206.  
  207.  
  208.  
  209. void DrawGameScreen(void)
  210. {
  211.     GWorldPtr        frontWorld;
  212.     GDHandle        frontGD;
  213.  
  214.     
  215.     if (!gWindow)
  216.         Fail(ResError(), __FILE__, __LINE__, TRUE);
  217.  
  218.     SetPortWindowPort(gWindow);
  219.     
  220.     GetGWorld(&frontWorld,&frontGD);                    // be sure we're in the about box
  221.     SetGWorld(gWorld, nil);
  222.     if (!LockPixels(GetGWorldPixMap(gWorld)))            // make sure everything is kosher
  223.         {
  224.         UpdateGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
  225.         if (!LockPixels(GetGWorldPixMap(gWorld)))
  226.             Fail(ResError(), __FILE__, __LINE__, TRUE);
  227.         }
  228.     
  229.     SetGWorld(frontWorld,frontGD);
  230.  
  231.     ForeColor(blackColor);                                // recommended by Apple when
  232.     BackColor(whiteColor);                                // using CopyBits drawing
  233.  
  234. #if GENERATING68K
  235.     if (gUseQuickdraw)
  236. #endif
  237.         CopyBits(&((GrafPtr)gWorld)->portBits,            // copy from GWorld
  238.                  &gWindow->portBits,                    // to window
  239.                  &gWorldRect,                            // using CopyBits
  240.                  &gDestinationRect, srcCopy, nil);
  241. #if GENERATING68K
  242.     else
  243.         CopyBlit(*srcPixHandle,
  244.                  *portPixMap,
  245.                  &gWorldRect,
  246.                  &gDestinationRect);                    // copy using CopyBlit
  247. #endif
  248.  
  249.     UnlockPixels(GetGWorldPixMap(gWorld));                // done drawing in about box    
  250.     DisposeGWorld(frontWorld);                            // Scrap our temporary GWorldPtr
  251.  
  252.     if (gGameOn && gShowFPS)
  253.         {
  254.         char            aStr[256];
  255.         long            tNow;
  256.  
  257.         ForeColor(whiteColor);
  258.         BackColor(blackColor);
  259.             
  260.         tNow = (TickCount() - gStartTicks);
  261.         if (!tNow)
  262.             tNow = 1;
  263.  
  264.         aStr[0] = sprintf(aStr+1, "Frame: %ld, fps: %2.2f   ", gFrameCount, (float)gFrameCount/(float)tNow * 60);
  265.         TETextBox(aStr + 1, aStr[0], &gInformationRect, teCenter);
  266.         }
  267.  
  268.     if (gGameOn)
  269.         ++gFrameCount;
  270. }
  271.  
  272.  
  273.  
  274. /**/
  275.  
  276.  
  277.  
  278. void *GetFramebufferMemory(void)
  279. {
  280.     return GetPixBaseAddr( GetGWorldPixMap( gWorld ) );
  281. }
  282.  
  283.  
  284.  
  285. /**/
  286.  
  287.  
  288.  
  289.  
  290.  
  291. void ShowPausedScreen(void)
  292. {
  293.     Str255        aStr = "\pGame Paused - press TAB to continue";
  294.     PenState    savePenState;
  295.  
  296.     GetPenState( &savePenState );    /* save current state */
  297.     ShowPen();                        /* we want pen to be visible */
  298.  
  299.     ForeColor(blackColor);
  300.     PenMode(patOr);
  301.     PenPat(&qd.gray);
  302.     PaintRect(&gDestinationRect);
  303.  
  304.     ForeColor(whiteColor);
  305.     BackColor(blackColor);
  306.  
  307.     TETextBox(aStr + 1, aStr[0], &gInformationRect, teCenter);
  308.  
  309.     SetPenState( &savePenState );    /* restore the pen's visible state */
  310. }
  311.  
  312.  
  313.  
  314.  
  315. void UpdateGameScreen(void)
  316. {
  317.     extern Intent    gIntent;
  318.     extern double    gravity;
  319.     extern View*    view;
  320.     extern World*    w;
  321.     extern Object*    me;
  322.     extern Object*    him;
  323.     extern Boolean    quitting;
  324.     
  325.     double    sin_facing, cos_facing;
  326.     double    fx, fy, fz;
  327.     fixed    shift = 0;
  328.  
  329.  
  330.     while (gIntent.n_special--)
  331.         {
  332.         switch (gIntent.special[gIntent.n_special])
  333.             {
  334.             case INTENT_END_GAME:
  335.                 ShowCursor();
  336.                 if (NoteAlert(300, nil) == 1)
  337.                     {
  338.                     quitting = TRUE;
  339.                     SetMBarState(SHOW);
  340.                     HideWindow(GetDialogWindow(gBackgroundWindow));
  341.                     }
  342.                 else
  343.                     HideCursor();
  344.                 break;
  345.                 
  346.             case INTENT_JUMP:
  347.             case INTENT_ACTION4:
  348.             case INTENT_ACTION5:
  349.                 object_apply_force(me, 0.0, 0.0, 50.0);
  350.                 break;
  351.                     
  352.             case INTENT_ACTION1:
  353.                 shift = FIXED_HALF_PI;    // Peek left (half turn left)
  354.                 break;
  355.                                          
  356.             case INTENT_ACTION2:
  357.                 shift = FIXED_PI;        // Peek behind (full turn)
  358.                 break;
  359.                     
  360.             case INTENT_ACTION3:
  361.                 shift = -FIXED_HALF_PI;    // Peek right (half turn right)
  362.                 break;
  363.                     
  364.             case INTENT_GROW_V:
  365.             case INTENT_SHRINK_V:
  366.                 break;
  367.             }
  368.         }
  369.  
  370.     /* Determine forces on viewer. */
  371.     sin_facing = sin(me->angle);
  372.     cos_facing = cos(me->angle);
  373.     fx = cos_facing * gIntent.force_x - sin_facing * gIntent.force_y;
  374.     fy = sin_facing * gIntent.force_x + cos_facing * gIntent.force_y;
  375.     fz = gravity * me->mass;  /* gravity */
  376.  
  377.     /* Apply the forces. */
  378.     object_apply_force(me, fx, fy, fz);
  379.     object_apply_torque(me, gIntent.force_rotate);
  380.     object_update(me);
  381.  
  382.     object_apply_force(him, fx, fy, 0.0);
  383.     object_update(him);
  384.  
  385.     /* Determine the view. */
  386.     object_view(me, view);
  387.         
  388.     if (shift)
  389.         ShiftViewpoint(view, FIXED_ZERO, FIXED_ZERO, FIXED_ZERO, shift);
  390.  
  391.     /* Display the world. */
  392.     Render(w, view);
  393.     DrawGameScreen();
  394. }